package com.fowo.api.controller.purchase;

import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fowo.api.common.model.IdListPo;
import com.fowo.api.common.model.ImportRow;
import com.fowo.api.common.model.OptionItem;
import com.fowo.api.common.model.R;
import com.fowo.api.common.util.ResponseUtils;
import com.fowo.api.controller.purchase.importPo.WarehouseBinImportPo;
import com.fowo.api.controller.purchase.importPo.WarehouseBinProductImportPo;
import com.fowo.api.controller.purchase.importPo.WarehouseBinTransferImportPo;
import com.fowo.api.controller.purchase.importPo.wareHouseInventoryImportPo;
import com.fowo.api.controller.purchase.vo.*;
import com.fowo.api.entity.*;
import com.fowo.api.inventory.entity.InventoryBatchNo;
import com.fowo.api.inventory.entity.InventoryPlacement;
import com.fowo.api.inventory.model.InventoryExchangeVo;
import com.fowo.api.inventory.model.PatternEnum;
import com.fowo.api.inventory.model.SimpleInventoryItem;
import com.fowo.api.inventory.model.TargetTypeEnum;
import com.fowo.api.inventory.model.form.InventoryExchangeFormVo;
import com.fowo.api.inventory.service.InventoryBusinessService;
import com.fowo.api.inventory.service.impl.InventoryBatchNoServiceImpl;
import com.fowo.api.inventory.service.impl.InventoryPlacementServiceImpl;
import com.fowo.api.mapper.WarehouseBinDMapper;
import com.fowo.api.model.listing.father.ListingFatherItemVo;
import com.fowo.api.model.listing.father.ListingFatherSearchParamPo;
import com.fowo.api.model.product.ProductItemVo;
import com.fowo.api.model.product.ProductSearchParamPo;
import com.fowo.api.model.shop.info.ShopInfoItemVo;
import com.fowo.api.model.shop.info.ShopInfoSearchParamPo;
import com.fowo.api.model.stock.in.StockInVo;
import com.fowo.api.model.stock.in.product.StockInProductItemVo;
import com.fowo.api.model.warehouse.bin.WarehouseBinItemVo;
import com.fowo.api.model.warehouse.bin.WarehouseBinSearchParamPo;
import com.fowo.api.model.warehouse.bin.WarehouseBinVo;
import com.fowo.api.model.warehouse.bin.products.WarehouseBinProductsItemVo;
import com.fowo.api.model.warehouse.bin.products.WarehouseBinProductsSearchParamPo;
import com.fowo.api.model.warehouse.bin.products.WarehouseBinProductsVo;
import com.fowo.api.service.WarehouseBinProductsService;
import com.fowo.api.service.WarehouseBinService;
import com.fowo.api.service.WarehouseService;
import com.fowo.api.service.impl.*;
import com.fowo.api.sys.entity.SysFile;
import com.fowo.api.sys.model.SysDictAllItem;
import com.fowo.api.sys.service.SysDictService;
import com.fowo.api.user.model.JwtUserInfo;
import com.fowo.api.util.LocalDateUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Tag(name = "仓位定制接口")
@RequestMapping("/api/warehouse-bin-D")
@RestController
public class WarehouseBinDController {
    @Resource
    private InventoryRealServiceImpl inventoryRealService;
    @Resource
    private WarehouseBinServiceImpl warehouseBinService;
    @Resource
    private WarehouseBinDServiceImpl warehouseBinDService;
    @Resource
    private WarehouseServiceImpl warehouseService;
    @Resource
    private WarehouseBinProductsServiceImpl warehouseBinProductsService;
    @Resource
    private WarehouseBinDMapper warehouseBinDMapper;
    @Resource
    private ProductServiceImpl productService;
    @Resource
    private ShopInfoServiceImpl shopInfoService;
    @Resource
    private SysDictService sysDictService;
    @Resource
    private ListingFatherServiceImpl listingFatherService;
    @Resource
    private InventoryBatchNoServiceImpl inventoryBatchNoService;
    @Resource
    private InventoryBusinessService inventoryBusinessService;
    @Resource
    private InventoryPlacementServiceImpl inventoryPlacementService;

    @Operation(summary = "新增仓位")
    @PostMapping
    public R<Long> create(@Validated @RequestBody WarehouseBinVo model) {
        WarehouseBin one = warehouseBinService.getOne(Wrappers.<WarehouseBin>query().lambda().eq(WarehouseBin::getStorageBin, model.getStorageBin())
                .eq(WarehouseBin::getWarehouseId,model.getWarehouseId()));
        Assert.isNull(one,model.getStorageBin()+"已存在");
        model.setSysType("1");
        model.setStatus("1");
        return R.data(() -> warehouseBinService.create(model));
    }
    //出库单获取仓位
    @Operation(summary = "出库单获取仓位库存")
    @PostMapping("outboundObtainInventory")
    public R<List<warehouseBin>> outboundObtainInventory(@RequestBody List<WarehouseBinProductsVo> list){
        List<warehouseBin> list2=new ArrayList<>();
        for(int i=0;i<list.size();i++){
            WarehouseBinProductsVo warehouseBinProductsVo = list.get(i);
            WarehouseBinParam search=new WarehouseBinParam();
            search.setProductId(warehouseBinProductsVo.getProductId());
            search.setShopId(warehouseBinProductsVo.getShopId());
            search.setFnskuName(warehouseBinProductsVo.getFnskuName());
            search.setWarehouseId(warehouseBinProductsVo.getParentId());
            List<warehouseBin> wareBin = warehouseBinDMapper.getWareBin2(search);
            warehouseBin warehouseBin=new warehouseBin();
            if(wareBin.size()>0){
                warehouseBin.setItemId(warehouseBinProductsVo.getId());
//                wareBin.forEach(x->x.setItemId(warehouseBinProductsVo.getId()));
                List<warehouseBin> good = wareBin.stream().filter(x -> x.getType() ==5||x.getType() ==2).collect(Collectors.toList());
                List<warehouseBin> bad =wareBin.stream().filter(x->x.getType()==6||x.getType() ==3).collect(Collectors.toList());
                warehouseBin.setGoodItems(good);
                warehouseBin.setBadItems(bad);
                list2.add(warehouseBin);
//                list2.addAll(wareBin);
            }
        }
        return  R.data(list2);
    }

    @Operation(summary = "getListing")
    @PostMapping("getListing")
    public R getListing(@RequestBody List<StockInProduct> list){
        List<StockInProduct> list2=new ArrayList<>();
        List<String> collect = list.stream().map(x -> x.getLxFnsku()).collect(Collectors.toList());
        if(collect.size()==0){
            return R.data(list2);
        }
        List<Long> shopIds = list.stream().map(x -> x.getShopId()).collect(Collectors.toList());
        if(shopIds.size()==0){
            return R.data(list2);
        }
        List<ListingFather> list1 = listingFatherService.list(Wrappers.<ListingFather>query().lambda()
                .in(ListingFather::getFnsku, collect).in(ListingFather::getShop, shopIds));
        return  R.data(list1);
    }


    @PostMapping("addBin")
    public R batchCreate() throws Exception {
         List<Warehouse> list = warehouseService.list();
        for(int i=0;i<list.size();i++){
            warehouseService.AddWarehouse(list.get(i).getId());
        }
        return R.ok(true);
    }

    //批量新增
    @Operation(summary = "批量新增仓位")
    @PostMapping("batchCreate")
    public R batchCreate(@Validated @RequestBody batchCreateWarehouseBinVo model) {
        List<String> position = getPositionName(model);
        createPosition(position,model);
        return R.ok(true);
    }
    @Operation(summary = "仓位转移和上架")
    @PostMapping("inventoryTransfer")
    @Transactional(rollbackFor = Exception.class)
    public R<Long> create(@Validated @RequestBody List<inventoryTurnoverVo> model) throws Exception {
        for(int i=0;i<model.size();i++){
            inventoryTurnoverVo inventoryTurnoverVo = model.get(i);
            //仓位转移
            InventoryExchangeFormVo formVo = prepareInventoryTurnover(inventoryTurnoverVo);
            inventoryBusinessService.exchange(formVo);
            //仓库转移
            InventoryExchangeFormVo formVo1 = prepareInventoryTurnover1(inventoryTurnoverVo);
            inventoryBusinessService.exchange(formVo1);

            final WarehouseBin warehouseBin = warehouseBinService.getById(inventoryTurnoverVo.getFromBinId());
            if(warehouseBin.getType().equals("5")){ // 可用仓位解除绑定关系
                LambdaQueryWrapper<WarehouseBinProducts> wrapper = Wrappers.lambdaQuery(WarehouseBinProducts.class)
                        .eq(WarehouseBinProducts::getParentId, inventoryTurnoverVo.getFromBinId())
                        .eq(WarehouseBinProducts::getProductId, inventoryTurnoverVo.getProductId());

                if(null == inventoryTurnoverVo.getFnskuName()){
                    wrapper.isNull(WarehouseBinProducts::getFnskuName);
                }else {
                    wrapper.eq(WarehouseBinProducts::getFnskuName, inventoryTurnoverVo.getFnskuName());
                }
                if(null == inventoryTurnoverVo.getShopId()){
                    wrapper.isNull(WarehouseBinProducts::getShopId);
                }else {
                    wrapper.eq(WarehouseBinProducts::getShopId, inventoryTurnoverVo.getShopId());
                }
                warehouseBinProductsService.remove(wrapper);
            }
        }
        return R.ok(true);
    }
    @Operation(summary = "上架获取仓位")
    @PostMapping("inventoryTransferGetWarehouseBin")
    public R<List<warehouseBinInventory>> inventoryTransferGetWarehouseBin(@RequestBody List<WarehouseBinParam> model) throws Exception {
        List<warehouseBinInventory> list=new ArrayList<>();
        for(int i=0;i<model.size();i++){
            WarehouseBinParam warehouseBinParam = model.get(i);
//            warehouseBinParam.setFSku(warehouseBinParam.getFnskuName());
            warehouseBinParam.setShopId(warehouseBinParam.getShopId());
            warehouseBinParam.setFSku(warehouseBinParam.getFnskuName());
            WarehouseBin byId = warehouseBinService.getById(warehouseBinParam.getStorageId());
            if(byId.getType().equals("2")){
                warehouseBinParam.setType((long) 5);//获取可用的仓位
            }else if(byId.getType().equals("3")){
                warehouseBinParam.setType((long) 6);//获取可用的仓位
            }
//            warehouseBinParam.setShopId(null);
            List<warehouseBinInventory> wareBin = warehouseBinDMapper.getWareBinOne(warehouseBinParam);
            if(wareBin!=null){
                list.addAll(wareBin);
            }
        }
        return R.data(list);
    }
    @Operation(summary = "上架获取仓位产品转移仓位2")
    @PostMapping("inventoryTransferGetWarehouseBinTransfer")
    public R<List<warehouseBinInventory>> inventoryTransferGetWarehouseBinTransfer(@RequestBody List<WarehouseBinParam> model){
        List<warehouseBinInventory> list=new ArrayList<>();
        for(int i=0;i<model.size();i++){
            WarehouseBinParam warehouseBinParam = model.get(i);
//            warehouseBinParam.setFnsku(warehouseBinParam.getFnsku());
            warehouseBinParam.setShopId(warehouseBinParam.getShopId());
            warehouseBinParam.setFSku(warehouseBinParam.getFnskuName());
            WarehouseBin byId = warehouseBinService.getById(warehouseBinParam.getStorageId());
            if(byId.getType().equals("5")){
                warehouseBinParam.setType((long) 5);
            }else if(byId.getType().equals("6")){
                warehouseBinParam.setType((long) 6);
            }
//            warehouseBinParam.setShopId(null);
            List<warehouseBinInventory>  wareBin = warehouseBinDMapper.getWareBinOne(warehouseBinParam);
            if(wareBin!=null){
                list.addAll(wareBin);
            }else{
                WarehouseBinParam warehouseBinParam1 =new WarehouseBinParam();
                if(byId.getType().equals("5")){
                    warehouseBinParam1.setType((long) 2);
                }else if(byId.getType().equals("6")){
                    warehouseBinParam1.setType((long) 3);
                }
//                wareBin =new ArrayList<warehouseBinInventory>();
//                WarehouseBin one = warehouseBinService.getOne(Wrappers.<WarehouseBin>query().lambda()
//                        .eq(WarehouseBin::getType, warehouseBinParam1.getType())
//                        .eq(WarehouseBin::getWarehouseId,warehouseBinParam.getWarehouseId()));
//                list.add(wareBin);
            }
        }
        return R.data(list);
    }

    @Operation(summary = "仓位绑定商品")
    @PostMapping("posBindProducts")
    public R create(@Validated @RequestBody WarehouseBinProductsVo model) {
        QueryWrapper<WarehouseBinProducts> queryWrapper=new QueryWrapper();
        queryWrapper.eq("parent_id",model.getParentId());
        queryWrapper.eq("product_id",model.getProductId());
        Assert.notNull(model.getParentId(),"parentId仓位的id不能为null");
        Assert.notNull(model.getProductId(),"productId产品的id不能为null");
        ListingFather byId2 = listingFatherService.getById(model.getFnsku());
        if(model.getShopId()!=null){
            queryWrapper.eq("shop_id",model.getShopId());
        }else{
            queryWrapper.isNull("shop_id");
        }
        if(model.getFnsku()!=null){
            queryWrapper.eq("fnsku_name",byId2.getFnsku());
            model.setFnskuName(byId2.getFnsku());
            model.setMsku(byId2.getMsku());
        }else{
            queryWrapper.isNull("fnsku_name");
        }
        WarehouseBinProducts one = warehouseBinProductsService.getOne(queryWrapper);
        Assert.isNull(one,"商品已绑定!");
        if(model.getAsin()==null){
            //查询在这个仓库下面是否已经绑定过了
            R bindingWarehouse = isBindingWarehouse(model, byId2);
            if(!bindingWarehouse.isSuccess()){
                R r = new R();
                r.setSuccess(false);
                r.setErrorMessage(bindingWarehouse.getErrorMessage());
                r.setMessage("201");
                return r;
            }
        }
        Product byId = productService.getById(model.getProductId());
        model.setSku(byId.getSku());
        model.setProductName(byId.getName());
        return R.data(() -> warehouseBinProductsService.create(model));
    }




    private R isBindingWarehouse(@RequestBody @Validated WarehouseBinProductsVo model, ListingFather byId2) {
      //判断这个是不是绑定其他仓位的
        WarehouseBin byId = warehouseBinService.getById(model.getParentId());
        WarehouseBinParam search=new WarehouseBinParam();
        search.setProductId(model.getProductId());
        search.setWarehouseId(byId.getWarehouseId());
        List<warehouseBin> wareBin = warehouseBinDMapper.getWareBin(search);
        if(wareBin.size()>0){
            //判断是不是一个仓位
            warehouseBin warehouseBin = wareBin.get(0);
           // Assert.isTrue(warehouseBin.getId().longValue()==model.getParentId().longValue(),"该产品已经绑定了仓位"+warehouseBin.getName());
            return R.fail("该产品已经绑定了仓位"+warehouseBin.getName());
        }
        return R.ok(true);
    }

    @Operation(summary = "仓位解除绑定商品")
    @DeleteMapping("secure/{id}")
    public R delete(@PathVariable Long id) throws Exception {
        WarehouseBinProductsVo voById = warehouseBinProductsService.getVoById(id);
        WarehouseBin byId = warehouseBinService.getById(voById.getParentId());
        QueryWrapper<InventoryPlacement> queryWrapper=new QueryWrapper();
        queryWrapper.eq("stock_id",byId.getWarehouseId());
        queryWrapper.eq("item_id",voById.getProductId());
        queryWrapper.eq("bin_id",byId.getId());
        if(voById.getShopId()!=null){
            queryWrapper.eq("shop_id",voById.getShopId());
        }else{
            queryWrapper.isNull("shop_id");
        }
        if(voById.getFnsku()!=null){
            queryWrapper.eq("fn_sku",voById.getFnskuName());
        }else{
            queryWrapper.isNull("fn_sku");
        }
        InventoryPlacement one = inventoryPlacementService.getOne(queryWrapper);
        if(one!=null){
            Assert.isTrue(one.getStockQty()==null||(one.getStockQty()!=null?one.getStockQty().intValue()==0:true),"库存为0才能回收");
            Assert.isTrue(one.getLockQty()==null||(one.getLockQty()!=null?one.getLockQty().intValue()==0:true),"库存为0才能回收");
            Assert.isTrue(one.getWayQty()==null||(one.getWayQty()!=null?one.getWayQty().intValue()==0:true),"库存为0才能回收");
        }
        return R.run(() -> warehouseBinProductsService.delete(id));
    }
    @Operation(summary = "仓位解除绑定商品")
    @DeleteMapping("secure/batch/{ids}")
    @Transactional(rollbackFor = Exception.class)
    public R delete(@PathVariable String ids) throws Exception {
        List<Long> idList = Arrays
                .asList(ids.split(","))
                .stream()
                .map(Long::valueOf)
                .collect(Collectors.toList());
        for(int i = 0; i <idList.size(); i++){
            delete(idList.get(i));
        }
        return R.ok(true);
    }
    @Operation(summary = "仓位删除")
    @DeleteMapping("warehouseBin/{id}")
    public R warehouseBinDelete(@PathVariable Long id) throws Exception {
        WarehouseBin byId = warehouseBinService.getById(id);
        List<WarehouseBinProducts> list = warehouseBinProductsService.list(Wrappers.<WarehouseBinProducts>query().lambda().eq(WarehouseBinProducts::getParentId, id));
        Assert.isTrue(list.size()==0,"请先删除绑定关系");
        QueryWrapper<InventoryPlacement> queryWrapper=new QueryWrapper();
        queryWrapper.select("sum(stock_qty) as  stock_qty,sum(lock_qty) as  lock_qty,sum(way_qty) as  way_qty");
        queryWrapper.eq("stock_id",byId.getWarehouseId());
        queryWrapper.eq("bin_id",byId.getId());
        //查询是否有库存
        InventoryPlacement one = inventoryPlacementService.getOne(queryWrapper);
        if(one !=null){
            Assert.isTrue(one.getStockQty()==null||(one.getStockQty()!=null?one.getStockQty().intValue()==0:true),"库存为0才能回收");
            Assert.isTrue(one.getLockQty()==null||(one.getLockQty()!=null?one.getLockQty().intValue()==0:true),"库存为0才能回收");
            Assert.isTrue(one.getWayQty()==null||(one.getWayQty()!=null?one.getWayQty().intValue()==0:true),"库存为0才能回收");
        }
        warehouseBinService.delete(id);
        return R.data(true);
    }
    @Operation(summary = "仓位删除")
    @DeleteMapping("warehouseBin/del")
    @Transactional(rollbackFor = Exception.class)
    public R warehouseBinDeletes(@RequestBody IdListPo po) throws Exception {

    for(int i=0;i<po.getIds().size();i++){
        Long aLong = po.getIds().get(i);
        warehouseBinDelete(aLong);
    }
        return R.data(true);
    }
    @Operation(summary = "回收仓位")
    @PostMapping("recoveryBin/{ids}")
    @Transactional(rollbackFor = Exception.class)
    public R<Long> create(@PathVariable String ids) {
        List<Long> idList = Arrays
                .asList(ids.split(","))
                .stream()
                .map(Long::valueOf)
                .collect(Collectors.toList());
        for(int i=0;i<idList.size();i++){
            WarehouseBin byId = warehouseBinService.getById(idList.get(i));
            QueryWrapper<InventoryPlacement> queryWrapper=new QueryWrapper();
            queryWrapper.select("sum(stock_qty) as  stock_qty,sum(lock_qty) as  lock_qty,sum(way_qty) as  way_qty");
            queryWrapper.eq("stock_id",byId.getWarehouseId());
            queryWrapper.eq("bin_id",byId.getId());
            //查询是否有库存
            InventoryPlacement one = inventoryPlacementService.getOne(queryWrapper);
            if(one !=null){
                Assert.isTrue(one.getStockQty()==null||(one.getStockQty()!=null?one.getStockQty().intValue()==0:true),"库存为0才能回收");
                Assert.isTrue(one.getLockQty()==null||(one.getLockQty()!=null?one.getLockQty().intValue()==0:true),"库存为0才能回收");
                Assert.isTrue(one.getWayQty()==null||(one.getWayQty()!=null?one.getWayQty().intValue()==0:true),"库存为0才能回收");
            }
            //先删除绑定关系
            warehouseBinProductsService.remove(Wrappers.<WarehouseBinProducts>query().lambda().eq(WarehouseBinProducts::getParentId,byId.getId()));
            //在删除仓位
//            warehouseBinService.removeById(byId.getId());
        }
        return  R.ok(true);
    }

    protected InventoryExchangeFormVo prepareInventoryTurnover1(inventoryTurnoverVo vo)
            throws Exception {
        JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();

        InventoryExchangeFormVo formVo = new InventoryExchangeFormVo();
        formVo.setFrom(TargetTypeEnum.Storage);
        formVo.setTo(TargetTypeEnum.Normal);
        formVo.setFormNum(null);
        formVo.setFormOperator(jwtUserInfo.getUserId().toString());
        formVo.setFromStockId(vo.getWid());
        formVo.setToStockId(vo.getWid());
        formVo.setModel(PatternEnum.FIFO);
        formVo.setDocumentType("仓位转移");

        SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
        inventoryItem.setId(vo.getProductId());
        InventoryExchangeVo exchangeItem = new InventoryExchangeVo();
        exchangeItem.setItem(inventoryItem);
        exchangeItem.setQty(BigDecimal.valueOf(vo.getQuantity()));
        exchangeItem.setShopId(
                String.valueOf(vo.getShopId()).equals("null")
                        ? null
                        : String.valueOf(vo.getShopId())
        );
        exchangeItem.setFnSku(
                String.valueOf(vo.getFnskuName()).equals("null")
                        ? null
                        : String.valueOf(vo.getFnskuName())
        );
        exchangeItem.setFromBinIdsType(TargetTypeEnum.Normal);
        exchangeItem.setToBinIdsType(TargetTypeEnum.Normal);
        exchangeItem.setCustomId(jwtUserInfo.getUserId());
        exchangeItem.setCustomBdId(null);
        formVo.add(exchangeItem);
        return formVo;
    }
    protected InventoryExchangeFormVo prepareInventoryTurnover(inventoryTurnoverVo vo)
            throws Exception {
        JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();

        InventoryExchangeFormVo formVo = new InventoryExchangeFormVo();
        formVo.setFrom(TargetTypeEnum.Normal);
        formVo.setTo(TargetTypeEnum.Normal);
        formVo.setFormNum(null);
        formVo.setFormOperator(jwtUserInfo.getUserId().toString());
        formVo.setFromStockId(vo.getWid());
        formVo.setToStockId(vo.getWid());
        formVo.setModel(PatternEnum.FIFO);
        formVo.setDocumentType("仓位转移");

            SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
            inventoryItem.setId(vo.getProductId());
            InventoryExchangeVo exchangeItem = new InventoryExchangeVo();
            exchangeItem.setItem(inventoryItem);
            exchangeItem.setQty(BigDecimal.valueOf(vo.getQuantity()));
            exchangeItem.setShopId(
                    String.valueOf(vo.getShopId()).equals("null")
                            ? null
                            : String.valueOf(vo.getShopId())
            );
            exchangeItem.setFnSku(
                    String.valueOf(vo.getFnskuName()).equals("null")
                            ? null
                            : String.valueOf(vo.getFnskuName())
            );
            Map<Long, Integer> binIds = new HashMap<>();
            binIds.put(
                    vo.getFromBinId(),
                    Integer.parseInt(
                            String.valueOf(vo.getQuantity()).equals("null")
                                    ? "0"
                                    : String.valueOf(vo.getQuantity())
                    )
            );
            exchangeItem.setFromBinIds(binIds);
            Map<Long, Integer> toBinIds = new HashMap<>();
            toBinIds.put(
                    vo.getToBinId(),
                    Integer.parseInt(
                            String.valueOf(vo.getQuantity()).equals("null")
                                    ? "0"
                                    : String.valueOf(vo.getQuantity())
                    )
            );
            exchangeItem.setToBinIds(toBinIds);
            exchangeItem.setFromBinIdsType(TargetTypeEnum.Normal);
            exchangeItem.setToBinIdsType(TargetTypeEnum.Normal);
            exchangeItem.setCustomId(jwtUserInfo.getUserId());
            exchangeItem.setCustomBdId(null);
            formVo.add(exchangeItem);
        return formVo;
    }
    @Operation(summary = "启用和禁用status 1是启用 2是关闭")
    @PostMapping("enableDisable")
    @Transactional(rollbackFor = Exception.class)
    public R update(@RequestBody IdListPo po,
                    @RequestParam(name = "status", required = false) String status
    ) {
        for(int i=0;i<po.getIds().size();i++){
            WarehouseBin byId = warehouseBinService.getById(po.getIds().get(i));
            byId.setStatus(status);
            warehouseBinService.updateById(byId);
        }
        return R.data(0);
    }

    @Operation(summary = "获取sku分页查询结果")
    @GetMapping("skuPage")
    public R<Page<ProductItemVo>> getPage(ProductSearchParamPo search) {
        return R.data(productService.pageSearch(search));
    }

    @Operation(summary = "获取店铺分页查询结果")
    @GetMapping("shopPage")
    public R<Page<ShopInfoItemVo>> getPage(ShopInfoSearchParamPo search) {
        return R.data(shopInfoService.pageSearch(search));
    }

    @Operation(summary = "获取fnsku分页查询结果")
    @GetMapping("fnskuPage")
    public R<Page<ListingFatherItemVo>> getPage(ListingFatherSearchParamPo search) {
        return R.data(listingFatherService.pageSearch(search));
    }
    @Operation(summary = "获取分页查询结果")
    @GetMapping("getWareBinUseTypeCount")
    public R<List<WarehouseBinItemDVo>> getWareBinUseTypeCount(WarehouseBinParam search) {
        List<WarehouseBinItemDVo> wareBinUseTypeCount = warehouseBinDMapper.getWareBinUseTypeCount2(search);
        return R.data(wareBinUseTypeCount);
    }
    @Operation(summary = "获取分页查询结果")
    @GetMapping("page")
    public R<Page<WarehouseBinItemDVo>> getPage(WarehouseBinParam search) {
        if(search.getSort()!=null){
            JSONObject jsonObject = JSON.parseObject(search.getSort());
            search.setSort((String) jsonObject.get("storageBin"));
        }
        Page<WarehouseBinItemDVo> warehouseBinItemVoPage = warehouseBinDMapper.pageSearch(search.toPage(), search);
        Set<Long> ids = warehouseBinItemVoPage.getRecords().stream().map(WarehouseBinItemDVo::getId).collect(Collectors.toSet());
        List<WarehouseBinProducts> list;
        if(ids.size()>0){
            list = warehouseBinDMapper.getWareBinProductsList(ids);
        } else {
            list = new ArrayList<>();
        }
        if(list.size()>0){
            warehouseBinItemVoPage.getRecords().forEach(x->{
                List<WarehouseBinProducts> collect = list.stream().filter(y -> y.getParentId().longValue() == x.getId().longValue()).collect(Collectors.toList());
                x.setProducts(collect);
            });
        }
        return R.data(warehouseBinItemVoPage);
    }

    @Operation(summary = "获取分页查询结果仓位")
    @GetMapping("reportFormsDVoPag")
    public R<Page<WarehouseBinreportFormsDVo>> reportFormsDVoPag(WarehouseBinParam search) throws Exception {
        Page<WarehouseBinreportFormsDVo> warehouseBinreportFormsDVoPage = warehouseBinDMapper.reportForms(search.toPage(), search);
        List<SysDictAllItem> scm00018 = sysDictService.getDictItems("SCM00018");
        warehouseBinreportFormsDVoPage.getRecords().forEach(x->{
//            if(x.getShopId()!=null){
//                ShopInfo byId = shopInfoService.getById(x.getShopId());
//                x.setShopName(byId.getShopName());
//            }
//            if(x.getFnSku()!=null){
//                ListingFather byId = listingFatherService.getById(x.getFnSku());
//                x.setFnSkuName(byId.getFnsku());
//            }
            Warehouse byId = warehouseService.getById(x.getWarehouseId());
            x.setWarehouseName(byId.getName());
//            Product byId1 = productService.getById(x.getProductId());
//            if(byId1!=null){
//                x.setProductName(byId1!=null?byId1.getName():null);
//                x.setSku(byId1.getSku());
//                x.setPicUrl(byId1.getPicUrl());
//            }

            List<SysDictAllItem> collect = scm00018.stream().filter(s -> Long.valueOf(s.getItemValue()).intValue() == x.getType().intValue()).collect(Collectors.toList());
            x.setTypeName(collect.get(0).getItemText());
        });
        return R.data(warehouseBinreportFormsDVoPage);
    }

    @Operation(summary = "设置仓位信息")
    @PutMapping
    public R update(@RequestBody WarehouseBinVo model) {
        return R.run(() -> warehouseBinService.update(model));
    }

    @Operation(summary = "获取分页查询结果仓库")
    @GetMapping("WareReportForms")
    public R<Page<WareReportFormsDvo>> WareReportForms(WarehouseBinParam search) {
        Page<WareReportFormsDvo> warehouseBinreportFormsDVoPage = warehouseBinDMapper.WareReportForms(search.toPage(), search);
        warehouseBinreportFormsDVoPage.getRecords().forEach(x->{
            if(x.getShopId()!=null){
                ShopInfo byId = shopInfoService.getById(x.getShopId());
                x.setShopName(byId.getShopName());
            }
            if(x.getFnSku()!=null){
                ListingFather byId = listingFatherService.getById(x.getFnSku());
                x.setFnSkuName(byId.getFnsku());
            }
            Warehouse byId = warehouseService.getById(x.getWarehouseId());
            x.setWarehouseName(byId!=null?byId.getName():null);
            Product byId1 = productService.getById(x.getProductId());
            if(byId1!=null){
                x.setProductName(byId1!=null?byId1.getName():null);
                x.setSku(byId1.getSku());
                x.setPicUrl(byId1.getPicUrl());
            }
            WarehouseBinParam WarehouseBinParam=new WarehouseBinParam();
            WarehouseBinParam.setFnsku(x.getFnSku());
            WarehouseBinParam.setShopId(x.getShopId());
            WarehouseBinParam.setWarehouseId(x.getWarehouseId());
            WarehouseBinParam.setProductId(x.getProductId());
            List<warehouseBin> wareBin = warehouseBinDMapper.getWareBin(WarehouseBinParam);

                //15天之前的
                Date date15 = LocalDateUtils.addDateDays(new Date(), -15);
                Long qty = getQty(x.getShopId(), x.getWarehouseId(), x.getProductId(), x.getFnSku(), date15,new Date());
                x.setAgeStockAge15(qty);
                Date date16 = LocalDateUtils.addDateDays(new Date(), -16);
                Date date30 = LocalDateUtils.addDateDays(new Date(), -30);
                Long qty2 = getQty(x.getShopId(), x.getWarehouseId(), x.getProductId(), x.getFnSku(),date30,date16);
                x.setAgeStockAge30(qty2);
                Date date31 = LocalDateUtils.addDateDays(new Date(), -31);
                Date date90 = LocalDateUtils.addDateDays(new Date(), -90);
                Long qty3 = getQty(x.getShopId(), x.getWarehouseId(), x.getProductId(), x.getFnSku(),date90,date31);
                x.setAgeStockAge90(qty3);
                Date date91 = LocalDateUtils.addDateDays(new Date(), -91);
                Long qty4 = getQty(x.getShopId(), x.getWarehouseId(), x.getProductId(), x.getFnSku(),date91, null);
                x.setAgeStockAge91(qty4);
                x.setWarehouseBins(wareBin);
        });
        return R.data(warehouseBinreportFormsDVoPage);
    }

    @Operation(summary = "导入仓位预览")
    @PostMapping("import-preview")
    public R<List<ImportRow<WarehouseBinImportPo>>> importPreview(
            @RequestBody SysFile sysFile,
            @RequestParam(name = "template", required = false) Long templateId,
            @RequestParam(name = "wid", required = false) Long wid,
            @RequestParam(
                    name = "allowOverrides",
                    defaultValue = "false"
            ) boolean allowOverrides
    ) {
        return R.data(() ->
                warehouseBinDService.importPreview(sysFile, templateId, allowOverrides,wid)
        );
    }
    @Operation(summary = "导入仓位完成")
    @PostMapping("import-done")
    public R importDone(
            @RequestBody   List<ImportRow<WarehouseBinImportPo>> rows,
            @RequestParam(name = "wid", required = false) Long wid,
            @RequestParam(name = "template", required = false) Long templateId
    ) {
        return R.run(() -> warehouseBinDService.importDone(rows, templateId,wid));
    }
    @Operation(summary = "导出仓位")
    @GetMapping("export")
    public void export(
            @RequestParam(name = "template", required = false) Long templateId,
            WarehouseBinParam search,
            HttpServletResponse response
    ) throws Exception {
        return;
//        warehouseBinDService.exportCangWei(templateId, search, response);
    }
    @Operation(summary = "下载导入仓位模版")
    @GetMapping("import/template")
    public void downloadImportTemplate(HttpServletResponse response)
            throws IOException {
        ResponseUtils.setAttachmentFileName(response, "导入创建仓位-0512.xlsx");
        InputStream inputStream = new ClassPathResource(
                "templates/0512.xlsx"
        )
                .getInputStream();
        StreamUtils.copy(inputStream, response.getOutputStream());
    }

    @Operation(summary = "下载仓位转移模版")
    @GetMapping("import/downloadTemplate")
    public void DownloadTemplate(HttpServletResponse response)
            throws IOException {
        ResponseUtils.setAttachmentFileName(response, "Location-Adjustment.xlsx");
        InputStream inputStream = new ClassPathResource(
                "templates/Location-Adjustment.xlsx"
        )
                .getInputStream();
        StreamUtils.copy(inputStream, response.getOutputStream());
    }

    @Operation(summary = "导入仓位转移")
    @PostMapping("import-preview3")
    public R<List<ImportRow<WarehouseBinTransferImportPo>>> preview3(
            @RequestBody SysFile sysFile,
            @RequestParam(name = "template", required = false) Long templateId,
            @RequestParam(name = "wid", required = false) Long wid,
            @RequestParam(
                    name = "allowOverrides",
                    defaultValue = "false"
            ) boolean allowOverrides
    ) {
        return R.data(() ->
                warehouseBinDService.importPreview3(sysFile, templateId, allowOverrides,wid)
        );
    }



    @Operation(summary = "下载导入仓位绑定关系")
    @GetMapping("import/template2")
    public void template2(HttpServletResponse response)
            throws IOException {
        ResponseUtils.setAttachmentFileName(response, "导入创建仓位与产品关系-0840.xlsx");
        InputStream inputStream = new ClassPathResource(
                "templates/0840.xlsx"
        )
                .getInputStream();
        StreamUtils.copy(inputStream, response.getOutputStream());
    }

    @Operation(summary = "导入预览仓位和产品绑定")
    @PostMapping("import-preview2")
    public R<List<ImportRow<WarehouseBinProductImportPo>>> importPreview2(
            @RequestBody SysFile sysFile,
            @RequestParam(name = "template", required = false) Long templateId,
            @RequestParam(name = "wid", required = false) Long wid,
            @RequestParam(
                    name = "allowOverrides",
                    defaultValue = "false"
            ) boolean allowOverrides
    ) {
        return R.data(() ->
                warehouseBinDService.importPreview2(sysFile, templateId, allowOverrides,wid)
        );
    }
    @Operation(summary = "导入完成仓位和产品绑定")
    @PostMapping("import-done2")
    public R done2(
            @RequestBody   List<ImportRow<WarehouseBinProductImportPo>> rows,
            @RequestParam(name = "template", required = false) Long templateId,
            @RequestParam(name = "wid", required = false) Long wid
    ) {
        return R.run(() -> warehouseBinDService.importDone2(rows, templateId,wid));
    }

    @Operation(summary = "导出仓位和产品绑定")
    @GetMapping("export22")
    public void export22(
            @RequestParam(name = "template", required = false) Long templateId,
            WarehouseBinParam search,
            HttpServletResponse response
    ) throws Exception {
        JwtUserInfo jwtUserInfo = JwtUserInfo.fromHeader();
        if (jwtUserInfo != null) {
            search.setCurrentUserId(jwtUserInfo.getUserId());
        }
        warehouseBinDService.exportCangWeiGuanXi(templateId, search, response);
    }
    @Transactional(rollbackFor = Exception.class)
    public void createPosition(List<String> position, batchCreateWarehouseBinVo model){
        Warehouse byId = warehouseService.getById(model.getParentWarehouse());
        Assert.notNull(byId,"仓库不存在");
        List<WarehouseBin> list = warehouseBinService.list(Wrappers.<WarehouseBin>query().lambda()
                .eq(WarehouseBin::getWarehouseId,byId.getId())
                .in(WarehouseBin::getStorageBin, position));
        Assert.isTrue(list.size()==0,"仓位已存在:"+list.stream().map(WarehouseBin::getStorageBin).collect(Collectors.joining()));
        List<WarehouseBin> WarehouseBins=new ArrayList<>();
        position.forEach(x->{
            WarehouseBin warehouseBin=new WarehouseBin();
            warehouseBin.setWarehouseId(model.getParentWarehouse());
            warehouseBin.setStorageBin(x);
            warehouseBin.setStatus("1");
            warehouseBin.setType(model.getType());
            warehouseBin.setUseType("2");
            warehouseBin.setSysType("1");
            WarehouseBins.add(warehouseBin);
        });
        warehouseBinService.saveBatch(WarehouseBins);
    }


    @Operation(summary = "导入初始化库存")
    @PostMapping("import-initialization-inventory")
    public R<List<ImportRow<wareHouseInventoryImportPo>>> importInitializationInventory(
            @RequestBody SysFile sysFile,
            @RequestParam(name = "template", required = false) Long templateId,
            @RequestParam(
                    name = "allowOverrides",
                    defaultValue = "false"
            ) boolean allowOverrides
    ) {
        return R.data(() ->
                warehouseBinDService.importInitializationInventory(sysFile, templateId, allowOverrides)
        );
    }
    @Operation(summary = "导入初始化库存")
    @PostMapping("import-initialization-inventory-done")
    public R importInitializationInventorydone(
            @RequestBody  List<ImportRow<wareHouseInventoryImportPo>> rows
    ) throws Exception {
        warehouseBinDService.importDone3(rows);
        return R.ok(true);
    }

    List<String>  getPositionName(batchCreateWarehouseBinVo model){
        List<String> positionList=new ArrayList<>();
        //区
        String area=model.getArea();
        //行
        List RowList = getList(model.getRowMin(), model.getRowMax());
        //列
        List LineMinList =  getList(model.getLineMin(),model.getLineMax());
        //层
        List StoreyList =  getList(model.getStoreyMin(),model.getStoreyMax());
         //格
        List FrameList =   getList(model.getFrameMin(),model.getFrameMax());
        for(int i=0;i<RowList.size();i++){
            StringBuilder post=new StringBuilder();
            post.append(area);
            post.append("-");
            post.append(RowList.get(i));
            for(int z=0;z<LineMinList.size();z++){
                StringBuilder post1=new StringBuilder();
                post1.append(post);
                post1.append("-");
                post1.append(LineMinList.get(z));
                if(StoreyList.size()>0){
                    for(int x=0;x<StoreyList.size();x++){
                        StringBuilder post2=new StringBuilder();
                        post2.append(post1);
                        post2.append("-");
                        post2.append(StoreyList.get(x));
                        if(FrameList.size()>0){
                            for(int k=0;k<FrameList.size();k++){
                                StringBuilder post3=new StringBuilder();
                                post3.append(post2);
                                post3.append("-");
                                post3.append(FrameList.get(k));
                                positionList.add(post3.toString());
                            }
                        }else{
                            positionList.add(post2.toString());
                        }
                    }
                }else{
                    positionList.add(post1.toString());
                }
            }
        }
            return  positionList;
    };

    List getList(String start,String end){
        List list=new ArrayList();
        if(start==null||end==null){
            return list;
        }
        Assert.isTrue((StringUtils.isNumeric(start)&&StringUtils.isNumeric(end))||(!StringUtils.isNumeric(start)&&!StringUtils.isNumeric(end)),"类型不对,同为数字或者同为字母");
        //行 判断是否是数字
        if(StringUtils.isNumeric(start)&&StringUtils.isNumeric(end)){
            Assert.isTrue(Integer.parseInt(end)>=Integer.parseInt(start),"请输入正确的整数范围");
            for (int i=Integer.parseInt(start);i<=Integer.parseInt(end);i++)
            {
                list.add(i<10?"0"+i:i);
            }
        }
        //否则是字母
        else{
            Assert.isTrue(start.length()==1&&end.length()==1,"只能输入单字母");
            int startA=Character.valueOf(start.charAt(0));
            int endB=Character.valueOf(end.charAt(0));
            Assert.isTrue(endB>=startA,"请输入正确的字母范围");
            for (int i=startA;i<=endB;i++)
            {
                char i1 = (char) i;
                String s = String.valueOf(i1).toUpperCase();
                list.add(s);
            }
        }
        return list;
    }

    Long getQty(Long shopId, Long Wid, Long productId, Long fnSku, Date startDate,Date endDate){
            QueryWrapper<InventoryBatchNo> queryWrapper=new QueryWrapper();
            queryWrapper.select("sum(stock_qty) as  stock_qty");
            queryWrapper.eq("stock_id",Wid);
            queryWrapper.eq("item_id",productId);
            if(shopId!=null){
                queryWrapper.eq("shop_id",shopId);
            }else{
                queryWrapper.isNull("shop_id");
            }
            if(fnSku!=null){
                queryWrapper.eq("fn_sku",fnSku);
            }else{
                queryWrapper.isNull("fn_sku");
            }
            if(startDate!=null&&endDate!=null){
                queryWrapper.between("create_time", LocalDateUtils.format(startDate,LocalDateUtils.DATE_PATTERN)+" 00:00:00",LocalDateUtils.format(endDate,LocalDateUtils.DATE_PATTERN)+" 23:59:59");
            }else{
                queryWrapper.le("create_time", LocalDateUtils.format(startDate,LocalDateUtils.DATE_PATTERN)+" 23:59:59");
            }
            InventoryBatchNo one = inventoryBatchNoService.getOne(queryWrapper);
            return one!=null?one.getStockQty().longValue():0;
    }

    @Operation(summary = "获取仓库默认仓位")
    @GetMapping("/getBinByWarehouse")
    public R<List<WarehouseBinStockVo>> getBinByWarehouse(WarehouseBinParam search) throws Exception {
        return R.data(warehouseBinDService.getBinByWarehouse(search));
    }

    @Operation(summary = "获取仓库仓位分页")
    @GetMapping("/getBinByWarehousePage")
    public R<Page<WarehouseBinStockVo>> getBinPageByWarehouse(WarehouseBinParam search) throws Exception{
        Page<WarehouseBinStockVo> binPageByWarehouse = warehouseBinDService.getBinPageByWarehouse(search);
        return R.data(binPageByWarehouse);
    }

    @Operation(summary = "获取入库仓位分页")
    @GetMapping("/getStockInBinPage")
    public R<Page<WarehouseBin>> getInBinPage(WarehouseBinParam search) throws Exception {
        return R.data(warehouseBinDService.getStockInBinPage(search));
    }

    @Operation(summary = "快速查询入库仓位选项")
    @GetMapping("/options")
    public R<List<OptionItem<WarehouseBinItemVo>>> searchOptions(WarehouseBinParam search) throws Exception {
        return R.data(warehouseBinDService.searchOptions(search));
    }
}
